feat(workflows): add workflow editor - #6248
Conversation
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
7183d58 to
76a8c2a
Compare
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent
Requesting changes at exact head b59375b5d71da234b26727baa9223456cf6351e3.
[P1] The editor teaches a trigger condition that cannot execute
desktop/src/features/workflows/ui/WorkflowFormBuilder.tsx:58-72 suggests contains(text, "deploy"), but the executor registers str_contains(...) and exposes message content as trigger_text (crates/buzz-workflow/src/executor.rs:203-223,232-242,289-300). The working syntax is already used in WorkflowStepCard.tsx:378 and desktop/tests/e2e/workflows.spec.ts:260: str_contains(trigger_text, "deploy").
The editor serializes this field unchanged, and evaluation errors are only logged before the workflow is skipped (crates/buzz-workflow/src/lib.rs:904-927). A user following the product's own example can therefore save a workflow that silently never fires. Please correct the example and add a regression assertion for the visible trigger-condition guidance.
[P1] The PR's changed Desktop smoke test is deterministically failing
desktop/tests/e2e/navigation.spec.ts:139-142 scopes the trigger assertion under getByRole("dialog", { name: workflowName }), but the dialog's accessible name is Edit workflow; the workflow name is separate content. The trigger node is rendered, yet the locator cannot reach it. CI run 32201513980, job 95916252006, failed the test on the initial attempt and both retries, leaving the aggregate Desktop gate red. Independent exact-head reproduction after pnpm build:e2e failed at the same line with the same accessibility snapshot.
Please scope the locator by the stable dialog title and assert the workflow name separately, following desktop/tests/e2e/workflows.spec.ts:812-815, then rerun the required smoke gate.
Validation at this exact head and clean worktree:
cargo test -p buzz-workflow— 156 passed, 2 ignoredjust desktop-test— 5045 passedjust desktop-typecheck— passed- targeted changed smoke test — failed reproducibly as described above
The reaction-trigger schema/runtime expansion was traced through crates/buzz-workflow/src/schema.rs:45-52 and crates/buzz-workflow/src/lib.rs:878-1001; no additional material relay, identity, persistence, or release-boundary issue was found in the 27-file base-to-head diff.
Co-authored-by: Codex <noreply@openai.com> Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
dd89361 to
967283c
Compare
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
…oundation * origin/main: Add appearance preference previews (#6193) fix(desktop): restore emoji recents (#6263) chore: serialize mobile pre-push checks (#6322) fix(buzz-acp): loosen workspace-scan guardrail to allow named paths (#6261) fix(buzz-dev-mcp): expand leading ~ in read_file/str_replace paths (#6271) perf(desktop): move five hot renderer paths from JS into Rust (#6024) fix(media): accept portrait video resolutions (#6058) Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
|
Addressed the requested review changes:
Validation:
Updated by Carl, an AI agent 🤖 |
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
|
Implemented the two adversarial-review blockers:
Validation at
AI-generated implementation and summary by Carl. |
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
…oundation Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent
Approved at exact head 59bee36684651e3f250a26b78f1f5f49993d26e8 against base 9c2f05346fdf3f058e4c579f6eea03dbe65fcca4. The two prior blockers are cleared, and the full re-review found no remaining material issue.
- The condition-builder guidance now uses executor-valid
str_contains(trigger_text, "deploy"), with visible E2E coverage. - The direct-route smoke now derives the target workflow ID, opens
/#/workflows/<id>, scopes assertions to theEdit workflowdialog, and checks the title and trigger independently. - Dirty route and overlay transitions defer the pending action until explicit discard; keeping the editor preserves the YAML draft.
- Deletion awaits completion, blocks dismissal while pending, and preserves the editor, draft, confirmation, and error state on rejection.
- Channel ingress and its query are experiment-gated, including defensive fallback if the flag changes while the view is active.
- Updates carry the opened revision; conflict failures preserve the local draft. The one-time webhook secret stays hidden by default and remains guarded across route/close transitions.
Exact-head evidence from clean worktrees:
cargo test -p buzz-workflow: 156 passed, 2 ignored.- Desktop unit suite: 5,115 passed.
- Desktop typecheck and static checks passed (only unrelated pre-existing diagnostics).
- Fresh isolated Playwright runs covered the two prior blockers plus dirty transitions, deletion failure recovery, feature-disabled/enabled channel ingress, stale-save behavior, and webhook-secret behavior. The targeted sets passed; one channel-ingress timeout passed on retry and again in an isolated 2.5s rerun.
- Required GitHub checks are green at this SHA (run
32316957536).
Invalid mixed-build Playwright attempts against an occupied port were discarded rather than counted. Residual risk is limited to the single recovered timing flake and the absence of native-app/live-relay manual validation; the clean isolated reruns, browser E2E coverage, core tests, and pinned CI are sufficient for this change.
The Reaction Added trigger exposed the emoji filter as a free-text input whose placeholder suggested a bare shortcode, even though execution compares the reaction event content verbatim. Use the prototype's shared emoji picker, preserve selected and legacy values in canonical YAML, and provide an explicit clear action for the optional filter. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent
Conditional re-review at exact head 76ebba7b7ace1e13445744200da70ca9da231b7e against base 9c2f05346fdf3f058e4c579f6eea03dbe65fcca4. I found no remaining material code defect in the repair delta, but I am not renewing approval while required CI is red and the user-visible change still lacks native-app evidence.
The repair is internally coherent:
- Reaction selection now stores the picker’s executor-compared value verbatim—native glyph or custom
:shortcode:—and preserves unsupported legacy text losslessly (desktop/src/features/workflows/ui/WorkflowEmojiField.tsx:43-93,desktop/src/features/workflows/ui/WorkflowFormBuilder.tsx:92-108,crates/buzz-workflow/src/lib.rs:888-900,951-956). - The channel-origin editor keeps its backing settings sheet mounted and returns to the Workflows subview without route churn (
desktop/src/features/channels/ui/ChannelManagementSheet.tsx:249-281). - Direct regression coverage exercises those contracts (
desktop/tests/e2e/channels.spec.ts:2987-3088,desktop/tests/e2e/workflow-reaction-picker.spec.ts:1-205). Both deliberate mutations—closing the backing sheet before overlay open and suppressing reactiononChange—caused the relevant assertions to fail before the sources were restored. - The six-file repair delta does not expand relay, schema, identity, persistence, or release scope.
Exact-head evidence from clean worktrees:
- Desktop static check and typecheck passed; reported diagnostics are pre-existing and outside the delta.
- Desktop unit suite passed: 5,115/5,115.
- Fresh E2E build passed.
- Two independent isolated Playwright selections passed, including a 9/9 product/adversarial set covering channel return, direct links, reaction persistence/clear/legacy/reload/narrow-window behavior, deletion rejection, and dirty-create close guarding.
- Mutation checks failed causally for both repaired behaviors; worktrees were restored clean.
- GitHub smoke shards, relay-backed E2E, Rust lint/unit, security, macOS build, and both Desktop integration shards are green at this SHA.
The remaining red Windows job is Windows Rust (x86_64-pc-windows-msvc) in run 32329719164, job 96308092910. Its sole failure is key_backup::tests::generated_passphrase_respects_word_count_and_separator (2,557 passed, 1 failed, 12 ignored). The PR does not touch desktop/src-tauri, Cargo configuration, or key backup. The unchanged test splits a generated phrase on -, while the unchanged EFF word list contains yo-yo (desktop/src-tauri/src/key_backup_tests.rs:231-247, desktop/src-tauri/src/assets/eff_short_wordlist_2_0.txt:1281), so a random draw can produce five split pieces for four selected words. The same job passed at the base SHA. This is strong evidence of an unrelated stochastic test defect, not a workflow-editor regression, but the required exact-head gate remains red and Desktop Core is still running at submission time.
Residual product risk: browser Playwright does not prove Tauri/WKWebView rendering, OS focus/input behavior, or native accessibility. No exact-head native Desktop recording, screenshots, or accessibility receipt was produced. Because this is a substantial user-visible editor, renew approval only after (1) the Windows failure is cleared by a clean rerun or repair and all required checks complete, (2) exact-head native-app behavior/accessibility evidence is attached or reviewed, and (3) the head remains unchanged.
wesbillman
left a comment
There was a problem hiding this comment.
Carl, an automated reviewer, commenting via Wes’s GitHub account.
Reviewing exact head 76ebba7b7ace1e13445744200da70ca9da231b7e against base 9c2f05346fdf3f058e4c579f6eea03dbe65fcca4.
[P2] Escape cannot dismiss the narrow node inspector
desktop/src/features/workflows/ui/WorkflowFormBuilder.tsx:695-711 presents the responsive inspector as a trapped aria-modal dialog, and :789-798 provides an explicit Close inspector action, but the inspector does not handle Escape. The enclosing workflow dialog owns dismissal instead.
Focused Playwright reproduction at 760×820:
- Open Create Workflow and select a channel so the trigger inspector is visible.
- Confirm the inspector is exposed as
role="dialog"witharia-modal="true". - Press Escape.
The workflow editor remains visible and the inspector also remains visible; a regression assertion expecting Escape to close the inspector fails deterministically. Depending on outer-editor dirty state/focus routing, this can also enter the editor-close path instead of dismissing the topmost modal layer. Keyboard users therefore cannot perform the inspector’s visible close action with the standard dialog key.
Please make the narrow inspector own Escape (close it and stop propagation) and add an E2E asserting the first Escape closes only the inspector while leaving the workflow editor open.
Focused evidence at this exact head: the Escape regression failed as described; a control reproduction confirmed dirty pathname navigation does show the existing discard guard, and the suspected stale custom-cron mode did not reproduce. I did not duplicate the broad CI suites.
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
|
🤖 AI-authored update Updated Escape ownership so dismissal follows the visible layer stack:
Regression coverage verifies the sequence at 760px and 1280px. At exact head |
jedwards27
left a comment
There was a problem hiding this comment.
Verdict: COMMENT (conditional; not approved)
Reviewed: 2e7583bf5ad5926ca32367af9954bc79d108e42d..13491c27154d4be3ee6bf2321050261517e5e652 (exact head 13491c27154d4be3ee6bf2321050261517e5e652)
Risk: high — this is a route-addressable, responsive editor that owns destructive/dirty-state transitions, webhook-secret handoff, exact-revision persistence, channel ingress, and keyboard/focus behavior.
Findings: no material code defect found at this head. The repair in WorkflowDialog.tsx:514-521 and WorkflowFormBuilder.tsx:523-540,701-729 now consumes the first Escape to close an open node inspector before allowing the outer editor to close. The regression test in workflows.spec.ts:162-184 covers both 760px and 1280px layouts. The reviewed delta does not alter the previously traced dirty/deletion/gating/revision/secret contracts; executor guidance remains str_contains(trigger_text, "deploy").
Behavior/contracts traced:
- Narrow inspector: named modal with trapped/looped focus; first Escape closes it, restores focus to its trigger, and retains the editor/route. Second Escape closes the editor.
- Wide inspector: complementary region with the same two-stage Escape behavior.
- Channel-origin edit/discard/create-cancel returns to the still-mounted channel Workflows panel without changing the channel URL (
channels.spec.ts:2987-3088). - Reaction values (glyph/custom/legacy) round-trip losslessly; clearing removes the optional YAML key, and the shared picker remains within an 800px viewport (
WorkflowEmojiField.tsx:43-93,workflow-reaction-picker.spec.ts:57-205). - Direct-route close, stale-save preservation, exact-revision update, and webhook-secret handoff were revalidated.
Exact-head validation: clean checkout; frozen install PASS; pnpm test 5,171/5,171 PASS; pnpm typecheck PASS; pnpm check PASS with four diagnostics outside the workflow files; pnpm build:e2e PASS; targeted Playwright 11/11 PASS; focus contract 2/2 PASS; narrow reaction picker 1/1 PASS. A mutation forcing closeInspector() to return false causally failed the Escape regression; restored source passed. Windows Rust is now green, clearing the earlier stochastic-test condition. At submission time, GitHub still has Desktop Core and Desktop E2E Integration shards 1/2 and 2/2 running; all completed required jobs are green.
Manual/native evidence: responsive Chromium captures and keyboard interaction evidence exist for narrow/medium/wide layouts. There is no exact-head Tauri/WKWebView run, MP4, screenshot, or semantic/AX receipt. Browser E2E does not establish native focus delivery, WKWebView layout, or native accessibility.
Residual risk / condition: do not treat this as approval until (1) all required checks finish green, (2) exact-13491c27154d4be3ee6bf2321050261517e5e652 native Tauri/WKWebView evidence is reviewed, and (3) the head remains unchanged. Any new head invalidates this review.
— :bot: Jude’s code review agent
wesbillman
left a comment
There was a problem hiding this comment.
Carl, an automated reviewer, commenting via Wes’s GitHub account.
Re-reviewed exact head 13491c27154d4be3ee6bf2321050261517e5e652 against base 2e7583bf5ad5926ca32367af9954bc79d108e42d.
The prior Escape blocker is resolved. The editor now gives an open trigger/step inspector first ownership of Escape in both responsive layouts: the first keypress clears the routed inspector pane and prevents outer-dialog dismissal; the next keypress follows the editor’s normal close/dirty-state lifecycle. The regression test covers 760px and 1280px.
I found no remaining material code defect in the repair delta. Persistence, YAML losslessness/unsupported-field handling, deletion/dirty transitions, reaction filters, exact-revision updates, and webhook-secret handling remain unchanged from the prior traced contracts. Focused exact-head Playwright reproduced the intended two-stage Escape behavior; a separate focused control verified switching a selected inspector to YAML does not leave stale Escape ownership. The worktree was clean before and after validation. All exact-head GitHub checks are green.
No approval submitted because Wes did not request approval. Residual risk is limited to the lack of an exact-head native Tauri/WKWebView accessibility run; browser E2E does not prove native focus delivery or the platform AX tree.
…-scoping * origin/main: perf(desktop): resolve references without directory scans (#6328) feat(llm): stamp thinking effort on call-completed log line (#6424) Fix cross-owner relay agent mentions in owner-only builds (#6338) feat(cli): accept Buzz message links for thread reads (#6359) feat(workflows): add workflow editor (#6248) fix(desktop): preserve huddle speech boundaries (#6397) test(desktop): use a wordlist-safe separator in passphrase word-count test (#6356) fix(models): curate Databricks alias-aware labels for 5 missing endpoints (#6360) fix(acp): guard against unrequested public relay skills (#6394) Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…ounting-and-solo * origin/main: (48 commits) fix(hooks): scope pre-push lanes to branch merge-base diff (#6423) Enforce a three-day dependency cooldown (#6426) perf(desktop): resolve references without directory scans (#6328) feat(llm): stamp thinking effort on call-completed log line (#6424) Fix cross-owner relay agent mentions in owner-only builds (#6338) feat(cli): accept Buzz message links for thread reads (#6359) feat(workflows): add workflow editor (#6248) fix(desktop): preserve huddle speech boundaries (#6397) test(desktop): use a wordlist-safe separator in passphrase word-count test (#6356) fix(models): curate Databricks alias-aware labels for 5 missing endpoints (#6360) fix(acp): guard against unrequested public relay skills (#6394) feat(desktop): refine context-aware Projects collaboration (#6396) fix(desktop): distinguish duplicate agent devices (#6337) feat(desktop): close Buzz window with Cmd+W (#6314) refactor(prompt): simplify Buzz agent guidance (#6340) feat(desktop): make Projects workspaces selectable (#6368) Add Buzz-native collaboration benchmarks (#6264) Polish mobile timeline and emoji interactions (#6297) feat(desktop): make the Projects overview follow the selected section (#6335) refactor(desktop): coordinate TTS playback (#6341) ... Signed-off-by: Atish Patel <atishpatel2012@gmail.com>
…ifications-pr * origin/main: (33 commits) fix(hooks): scope pre-push lanes to branch merge-base diff (#6423) Enforce a three-day dependency cooldown (#6426) perf(desktop): resolve references without directory scans (#6328) feat(llm): stamp thinking effort on call-completed log line (#6424) Fix cross-owner relay agent mentions in owner-only builds (#6338) feat(cli): accept Buzz message links for thread reads (#6359) feat(workflows): add workflow editor (#6248) fix(desktop): preserve huddle speech boundaries (#6397) test(desktop): use a wordlist-safe separator in passphrase word-count test (#6356) fix(models): curate Databricks alias-aware labels for 5 missing endpoints (#6360) fix(acp): guard against unrequested public relay skills (#6394) feat(desktop): refine context-aware Projects collaboration (#6396) fix(desktop): distinguish duplicate agent devices (#6337) feat(desktop): close Buzz window with Cmd+W (#6314) refactor(prompt): simplify Buzz agent guidance (#6340) feat(desktop): make Projects workspaces selectable (#6368) Add Buzz-native collaboration benchmarks (#6264) Polish mobile timeline and emoji interactions (#6297) feat(desktop): make the Projects overview follow the selected section (#6335) refactor(desktop): coordinate TTS playback (#6341) ... Signed-off-by: Tom Brow <tomb@block.xyz>
Two conflicts, both in the workflows route now that main shipped the workflow editor (block#6248): - WorkflowsRouteScreen.tsx: keep main's editor plumbing (editor prop, closeEditor, onCreate/onDuplicate/onEdit/onViewWorkflow) and this branch's `visibleChannels` filter, so workflows in open channels the owner has not joined still surface. - WorkflowsView.tsx: keep main's `editorWorkflowId` derivation alongside this branch's comment documenting why `channels` (not memberChannels) drives the aggregate query while the create-dialog picker stays membership-scoped. crates/buzz-acp/src/lib.rs merged cleanly: main's revert of the workflow attributed-author gate is preserved, and this branch's circuit_open / circuit_recovered observer alerts are intact. Signed-off-by: Michael Feth <michael@jira-flow.com>
* origin/main: (64 commits) chore(deps): pin earshot below 1.2.0 pending a VAD threshold re-pick (#6392) polish(desktop): finish Projects navigation and context chrome (#6429) fix(desktop): clarify add agents channel action (#6374) Repair stale large channel roster snapshots (#6251) feat(desktop-messages): show compact Buzz link metadata (#6252) feat(workflows): reply in-thread from send_message action (#6178) perf(desktop): split discover_acp_providers into cheap and forced paths (#6330) fix(desktop): restore recent channel sorting (#6402) fix(desktop): isolate main timeline stacking context from focus drawer (#6398) fix(desktop): make reconnect repair lossless (#6415) fix(hooks): scope pre-push lanes to branch merge-base diff (#6423) Enforce a three-day dependency cooldown (#6426) perf(desktop): resolve references without directory scans (#6328) feat(llm): stamp thinking effort on call-completed log line (#6424) Fix cross-owner relay agent mentions in owner-only builds (#6338) feat(cli): accept Buzz message links for thread reads (#6359) feat(workflows): add workflow editor (#6248) fix(desktop): preserve huddle speech boundaries (#6397) test(desktop): use a wordlist-safe separator in passphrase word-count test (#6356) fix(models): curate Databricks alias-aware labels for 5 missing endpoints (#6360) ... Signed-off-by: Luke Tornquist <tornquist@squareup.com>
…kflow-management * origin/main: (27 commits) chore(deps): pin earshot below 1.2.0 pending a VAD threshold re-pick (#6392) polish(desktop): finish Projects navigation and context chrome (#6429) fix(desktop): clarify add agents channel action (#6374) Repair stale large channel roster snapshots (#6251) feat(desktop-messages): show compact Buzz link metadata (#6252) feat(workflows): reply in-thread from send_message action (#6178) perf(desktop): split discover_acp_providers into cheap and forced paths (#6330) fix(desktop): restore recent channel sorting (#6402) fix(desktop): isolate main timeline stacking context from focus drawer (#6398) fix(desktop): make reconnect repair lossless (#6415) fix(hooks): scope pre-push lanes to branch merge-base diff (#6423) Enforce a three-day dependency cooldown (#6426) perf(desktop): resolve references without directory scans (#6328) feat(llm): stamp thinking effort on call-completed log line (#6424) Fix cross-owner relay agent mentions in owner-only builds (#6338) feat(cli): accept Buzz message links for thread reads (#6359) feat(workflows): add workflow editor (#6248) fix(desktop): preserve huddle speech boundaries (#6397) test(desktop): use a wordlist-safe separator in passphrase word-count test (#6356) fix(models): curate Databricks alias-aware labels for 5 missing endpoints (#6360) ... Signed-off-by: Luke Tornquist <tornquist@squareup.com> # Conflicts: # desktop/src/features/workflows/ui/WorkflowDeleteDialog.tsx # desktop/src/features/workflows/ui/WorkflowsView.tsx
…ntion-phase1 * origin/main: (37 commits) fix(desktop): sender names in notifications + macOS click-through routing (#6427) docs: clarify two-layer moderation ownership (#6481) Fix mobile thread tail and iOS channel header (#6399) chore(deps): pin earshot below 1.2.0 pending a VAD threshold re-pick (#6392) polish(desktop): finish Projects navigation and context chrome (#6429) fix(desktop): clarify add agents channel action (#6374) Repair stale large channel roster snapshots (#6251) feat(desktop-messages): show compact Buzz link metadata (#6252) feat(workflows): reply in-thread from send_message action (#6178) perf(desktop): split discover_acp_providers into cheap and forced paths (#6330) fix(desktop): restore recent channel sorting (#6402) fix(desktop): isolate main timeline stacking context from focus drawer (#6398) fix(desktop): make reconnect repair lossless (#6415) fix(hooks): scope pre-push lanes to branch merge-base diff (#6423) Enforce a three-day dependency cooldown (#6426) perf(desktop): resolve references without directory scans (#6328) feat(llm): stamp thinking effort on call-completed log line (#6424) Fix cross-owner relay agent mentions in owner-only builds (#6338) feat(cli): accept Buzz message links for thread reads (#6359) feat(workflows): add workflow editor (#6248) ... Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Category: new-feature
User Impact: Users can create, edit, duplicate, and deep-link to workflows in a responsive visual editor without losing unsupported YAML or unsaved work.
Problem: Workflow editing was split across disconnected surfaces and lacked reliable URL state, lifecycle protection, and parity between Form and YAML modes. Solution: This adds a route-addressable editor foundation with stable pane identity, guarded dirty exits, lossless Form/YAML transitions, responsive workflow and channel controls, and matching reaction-filter execution support.
File changes
crates/buzz-workflow/src/lib.rs
Apply reaction trigger filters during workflow execution and cover target-message gating.
crates/buzz-workflow/src/schema.rs
Extend the reaction trigger schema with the editor-owned filter field.
desktop/src/app/navigation/useAppNavigation.ts
Add navigation helpers for explicit workflow create, edit, and duplicate editor modes.
desktop/src/app/routes/WorkflowsRouteScreen.tsx
Coordinate route state with the shared workflow library and editor dialog.
desktop/src/app/routes/lazyWorkflowsRouteScreen.ts
Share one lazy route component across workflow route entry points to avoid loading flashes.
desktop/src/app/routes/workflows.$workflowId.tsx
Parse workflow editor modes and pane deep links for workflow-specific URLs.
desktop/src/app/routes/workflows.tsx
Parse library-level create state and render the shared workflow route screen.
desktop/src/app/AppWorkflowEditorOverlayProvider.tsx
Host the shared workflow editor at the app-shell level so channel-originated workflow dialogs stay above the active channel instead of replacing it.
desktop/src/shared/context/WorkflowEditorOverlayContext.tsx
Expose route-independent open-existing and create-new workflow actions to channel settings.
desktop/src/features/workflows/ui/WorkflowEditorHost.tsx
Share editor loading, unavailable, and dialog lifecycle wiring between canonical workflow routes and the channel overlay.
desktop/src/features/channels/ui/ChannelManagementSheet.tsx
Add an experiment-gated, Canvas-style Workflows ingress below Canvas, including channel-scoped loading, error, empty, and list states plus open/create actions; disabled users issue no workflow query.
desktop/src/features/channels/ui/ChannelWorkflowsSection.tsx
Render the channel workflow list and New workflow action without pushing the existing settings sheet past its file-size ceiling.
desktop/src/features/workflows/ui/ChannelCombobox.tsx
Adopt the final channel presentation, portalled scrolling, and one-shot create-flow opening behavior.
desktop/src/features/workflows/ui/CreateWorkflowDialog.tsx
Remove the superseded create-only dialog in favor of the unified workflow editor.
desktop/src/features/workflows/ui/WorkflowCard.tsx
Open workflow cards in the detail and run-history modal while preserving explicit edit and duplicate actions.
desktop/src/features/workflows/ui/WorkflowDetailDialog.tsx
Present workflow Trigger/Steps in the shared modal chrome, with top-chrome ingress to a responsive right-side run-history inspector and an explicit edit action.
desktop/src/features/workflows/ui/WorkflowDialog.tsx
Unify create, edit, and duplicate lifecycle handling with URL panes, generated-name synchronization, dirty-exit guards, stale-write preservation, and protected webhook-secret handoff.
desktop/src/features/workflows/ui/WorkflowFormBuilder.tsx
Build the responsive Form/YAML editor shell, stable step selection, insertion and removal behavior, and lossless canonical-YAML synchronization.
desktop/src/features/workflows/ui/WorkflowStepCard.tsx
Align workflow step controls and presentation with the final editor interaction model.
desktop/src/features/workflows/ui/WorkflowUnavailableDialog.tsx
Show a non-disclosing loading or unavailable state for missing and inaccessible workflow links, with retry and close actions.
desktop/src/features/workflows/ui/WorkflowWebhookSecretDialog.tsx
Obscure one-time webhook secrets by default and require explicit confirmation before any close or navigation discards them.
desktop/src/features/workflows/ui/WorkflowsScreen.tsx
Connect library state and workflow actions to the route-addressable editor.
desktop/src/features/workflows/ui/WorkflowsView.tsx
Restore the responsive workflow library, create tile, cards, loading states, and shared action menu.
desktop/src/features/workflows/ui/workflowEditorPane.test.mjs
Cover pane parsing, serialization, and stable step-ID reconciliation.
desktop/src/features/workflows/ui/workflowEditorPane.ts
Define explicit trigger and stable step pane URL state.
desktop/src/features/workflows/ui/workflowYamlDocument.ts
Read and update header fields independently of full form validation so incomplete steps cannot clear or disable the workflow title.
desktop/src/features/workflows/ui/workflowYamlDocument.test.mjs
Cover document-level workflow header reads and writes for incomplete definitions.
desktop/tests/e2e/workflow-title-stability.spec.ts
Verify generated, renamed, saved, and duplicated titles remain stable while moving between trigger and step panes.
desktop/src/features/workflows/ui/workflowFormTypes.test.mjs
Cover lossless Form/YAML round trips and actionable fallback for unsupported fields.
desktop/src/features/workflows/ui/workflowFormTypes.ts
Own canonical workflow YAML conversion while preserving supported trigger and step fields.
desktop/src/shared/ui/PortalledScrollArea.tsx
Provide bounded scrolling for popovers rendered outside their dialog container.
desktop/src/shared/ui/popover.tsx
Allow workflow popovers to use the shared portalled scroll container.
desktop/tests/e2e/channels.spec.ts
Cover disabled and enabled Workflows experiment states, including suppressed queries while disabled, placement beneath Canvas, channel workflow listing and opening, channel-preselected workflow creation, and direct return to the channel Workflows panel after close, discard, or cancel.
desktop/tests/e2e/workflows.spec.ts
Exercise library actions, deep links, create/edit/duplicate lifecycle, dirty exits, responsive editor behavior, YAML safety, stale updates, and one-shot channel selection.
Reproduction steps
Open Workflows and confirm the responsive card library, create tile, card action menu, and card-to-detail/run-history modal navigation.
Open
?view=create; confirm the channel chooser opens once, the trigger inspector stays hidden until a channel is selected, and closing the chooser does not make it reopen after unrelated edits.Create a workflow, switch between Form and YAML, add and remove steps, refresh a pane deep link, and confirm the selected trigger or stable step remains addressable.
Edit or duplicate a workflow, make an unsaved change, and confirm close, Escape, browser navigation, and route target changes require discard confirmation while pane-only navigation does not.
Enter unsupported YAML and confirm Form mode gives an actionable fallback without rewriting the definition; verify reaction triggers preserve and execute their filter.
Open a channel’s settings, select Workflows below Canvas, and open or create a workflow; confirm the shared modal stays over the channel, the channel URL does not change, New workflow preselects that channel, and closing or discarding returns directly to the channel’s Workflows panel.
In create, edit, and duplicate modes, move between the trigger and incomplete step panes and confirm the generated or edited title remains visible and editable.
Screenshots
Fresh captures from product head
c5c3abc91a71fe511d43e6cc9168b1626d0c217c; the later review-guidance fix does not alter these pictured states.Workflow library and actions
Workflow editor — wide
Workflow editor — narrow inspector overlay
Workflow editor — active channel overlay
Review feedback addressed
str_contains(trigger_text, "deploy")syntax and added a visible Playwright regression assertion.Edit workflowdialog name, asserted the workflow title separately, and retained the trigger-node assertion.workflowsexperiment, with defensive rendering if the flag changes while that view is active.Verification
Verified at exact pushed head
76ebba7b7ace1e13445744200da70ca9da231b7e:dc28ffa98ec34b4e0656757fb2dd93e60a84674d: 5/5 passed (picker interaction, canonical YAML persistence/clear, legacy-value preservation, save/reopen round trip, narrow viewport containment)dc28ffa98ec34b4e0656757fb2dd93e60a84674d: 36/36 passed3760c3d657a525f5af98e8d0f98bdd03999d8e61: 5,114/5,114 Desktop unit tests and the dirty-overlay/deletion focused checksRelated issue
None found. Closest prior work: #231.